// keel_gl.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"

#include <map>
#include <string>

#include "keel_gfx_GLGraphics.h"
#include "keel_gfx_NativeArray.h"

extern std::map<DWORD,std::string> g_glString;

JNIEXPORT jstring JNICALL Java_keel_gfx_GLGraphics_glGetStringPrivete
(JNIEnv *env, jclass, jint name)
{
	return env->NewStringUTF(g_glString[name].c_str());
}

//////////////////////////////////////////////////////////////////////////

int g_nTrashesCount;
int g_nTrashesSize=200;
void **g_nTrashes;

JNIEXPORT jlong JNICALL Java_keel_gfx_NativeArray_newNativeArray__ILjava_lang_Object_2
(JNIEnv *env, jobject, jint t, jobject o)
{
	int b=env->GetArrayLength(reinterpret_cast<jarray>(o));
	int s;
	switch ( t )
	{
	case GL_BYTE:
	case GL_UNSIGNED_BYTE:
		s = b;
		break;
	case GL_SHORT:
	case GL_UNSIGNED_SHORT:
		s = 2 * b;
		break;
	case GL_INT:
	case GL_UNSIGNED_INT:
	case GL_FLOAT:
		s = 4 * b;
		break;
	case GL_DOUBLE:
		s = 8 * b;
		break;
	default:
		return NULL;
	}

	void *buf=env->GetPrimitiveArrayCritical(reinterpret_cast<jarray>(o),NULL);
	if(buf)
	{
		void *ret=malloc(s);
		memcpy(ret,buf,s);
		env->ReleasePrimitiveArrayCritical(reinterpret_cast<jarray>(o),buf,0);

		return reinterpret_cast<jlong>(ret);
	}
	return NULL;
}

JNIEXPORT jlong JNICALL Java_keel_gfx_NativeArray_newNativeArray__II
(JNIEnv *, jobject, jint t, jint b)
{
	int s;
	switch ( t )
	{
	case GL_BYTE:
	case GL_UNSIGNED_BYTE:
		s = b;
		break;
	case GL_SHORT:
	case GL_UNSIGNED_SHORT:
		s = 2 * b;
		break;
	case GL_INT:
	case GL_UNSIGNED_INT:
	case GL_FLOAT:
		s = 4 * b;
		break;
	case GL_DOUBLE:
		s = 8 * b;
		break;
	default:
		return NULL;
	}
	return reinterpret_cast<jlong>(malloc(s));
}

JNIEXPORT void JNICALL Java_keel_gfx_NativeArray_deleteNativeArray
(JNIEnv *, jclass, jlong d)
{
	if(d)
	{
		if(g_nTrashes==NULL)
			g_nTrashes=new void*[g_nTrashesSize];
		g_nTrashes[g_nTrashesCount++]=reinterpret_cast<void*>(d);
		if(g_nTrashesCount>=g_nTrashesSize)
		{
			g_nTrashesSize+=1000;
			void **t=new void*[g_nTrashesSize];
			CopyMemory(t,g_nTrashes,g_nTrashesCount*sizeof(void *));
			delete[] g_nTrashes;
			g_nTrashes=t;
		}
	}
}

JNIEXPORT void JNICALL Java_keel_gfx_NativeArray_memcpy__JLjava_lang_Object_2III
(JNIEnv *env, jobject, jlong dst, jobject src, jint soffset, jint doffset, jint size)
{
	BYTE *sbuf=(BYTE*)env->GetPrimitiveArrayCritical(reinterpret_cast<jarray>(src),NULL);
	BYTE *dbuf=reinterpret_cast<BYTE *>(dst);
	memcpy(dbuf+doffset,sbuf+soffset,size);
	env->ReleasePrimitiveArrayCritical(reinterpret_cast<jarray>(src),sbuf,JNI_ABORT);
}

JNIEXPORT void JNICALL Java_keel_gfx_NativeArray_memcpy__Ljava_lang_Object_2JIII
(JNIEnv *env, jobject, jobject dst, jlong src, jint soffset, jint doffset, jint size)
{
	BYTE *dbuf=(BYTE*)env->GetPrimitiveArrayCritical(reinterpret_cast<jarray>(dst),NULL);
	BYTE *sbuf=reinterpret_cast<BYTE *>(src);
	memcpy(dbuf+doffset,sbuf+soffset,size);
	env->ReleasePrimitiveArrayCritical(reinterpret_cast<jarray>(dst),dbuf,JNI_ABORT);
}

JNIEXPORT void JNICALL Java_keel_gfx_NativeArray_memcpy__JIJII
(JNIEnv *, jclass, jlong src, jint soffset, jlong dst, jint doffset, jint size)
{
	BYTE *sbuf=reinterpret_cast<BYTE *>(src);
	BYTE *dbuf=reinterpret_cast<BYTE *>(dst);
	memcpy(dbuf+doffset,sbuf+soffset,size);
}

JNIEXPORT void JNICALL Java_keel_gfx_NativeArray_compact
(JNIEnv *, jclass, jboolean)
{
	for(int i=0;i<g_nTrashesCount;++i)
		free(g_nTrashes[i]);
	g_nTrashesCount=0;
}

